package com.huang.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.*;

/**
 * 线程工具类
 *
 * @author Ikaros
 * @since 2025/9/5 16:05 星期五
 */
public class ThreadUtils {

    private static final Logger logger = LoggerFactory.getLogger(ThreadUtils.class);

    private static final long OVERTIME = 120;

    /**
     * 停止线程池
     * 先使用shutdown, 停止接收新任务并尝试完成所有已存在任务.
     * 如果超时, 则调用shutdownNow, 取消在workQueue中Pending的任务,并中断所有阻塞函数.
     * 如果仍然超時，則強制退出.
     * 另对在shutdown时线程本身被调用中断做了处理.
     */
    public static boolean shutdownAndAwaitTermination(ExecutorService pool, String poolName) {
        if (pool == null || pool.isShutdown()) return true;
        pool.shutdown();
        try {
            if (!pool.awaitTermination(OVERTIME, TimeUnit.SECONDS)) {
                logger.warn("[{}] 线程池未在{}秒内优雅关闭，强制shutdownNow", poolName, OVERTIME);
                pool.shutdownNow();
                if (!pool.awaitTermination(OVERTIME, TimeUnit.SECONDS)) {
                    logger.error("[{}] 线程池仍未终止，可能存在资源泄漏", poolName);
                    return false;
                }
            }
        } catch (InterruptedException ie) {
            logger.warn("[{}] 线程池关闭时被中断", poolName);
            pool.shutdownNow();
            Thread.currentThread().interrupt();
        }
        logger.info("[{}] 线程池已优雅关闭", poolName);
        return true;
    }

    /**
     * 打印线程异常信息
     */
    public static void printException(Runnable r, Throwable t) {
        if (t == null && r instanceof Future<?> future) {
            try {
                if (future.isDone()) {
                    future.get();
                }
            } catch (CancellationException ce) {
                t = ce;
            } catch (ExecutionException ee) {
                t = ee.getCause();
            } catch (InterruptedException ie) {
                Thread.currentThread().interrupt();
            }
        }
        if (t != null) {
            logger.error(t.getMessage(), t);
        }
    }
}

